import Dingo.API as api
import random
import Dingo.models.OneHopP2P as P2P

__author__ = "Sarah Mount"

class TheSimulation(api.Simulation):
	def __init__(self, graph):
		ether = api.Ether(self)
		num_nodes = 350
		sensors = (CommunicatingSensor(graph, ether, i, num_nodes) for i in xrange(num_nodes))
		api.Simulation.__init__(self, sensors, graph)
	def run(self):
		super(TheSimulation, self).run()
	
class CommunicatingSensor(api.Sensor):
	def __init__(self, graph, ether, i, num_nodes):
		x = random.randrange(400)
		y = random.randrange(500)
		api.Sensor.__init__(self, graph, "S%d" % i, (x, y), 
				api.SensorColor.FromName("Grey"), 
				api.Scheduler([SendTask(self, num_nodes), RecvTask(self)], -1), 
				ether,
				P2P.OneHopP2P())
		return

class ColourPacket(api.Packet):
	"""Defines packets to be sent across the network.
	This one just sends sensor colours. When a sensor receives
	a message, it should change colour according to the message
	it's received.
	"""
	def __init__(self, sender_id, receiver_id, msg):
		api.Packet.__init__(self, sender_id, receiver_id, msg)
		return

class SendTask(api.Task):
	def __init__(self, sensor, num_nodes):
		api.Task.__init__(self, 0, 0, sensor)
		self.num_nodes = num_nodes
	def task(self):
		self.receiver_id = "S%d" % random.randint(0, self.num_nodes-1)
		# Don't send anything to "this" node
		while (self.receiver_id == self.sensor.id):
			self.receiver_id = "Sensor%d" % random.randint(0, self.num_nodes-1)
		rgb = random.randrange(1<<24)
		msg = api.SensorColor.FromRGBCombined(rgb)
		packet = ColourPacket(self.sensor.id, self.receiver_id, msg)
		self.sensor.send_q.put(packet) 		
		self.sensor.send(api.SensorColor.FromName("Grey"))  
		sleeptime = random.uniform(1, 2)
		api.Sleep(sleeptime)
		return

class RecvTask(api.Task):
	def __init__(self, sensor):
		api.Task.__init__(self, 1, 0, sensor)
	def task(self):
		self.sensor.setColour(api.SensorColor.FromName("Black"))
		while not self.sensor.recv_q.empty(): 
			msg = self.sensor.recv_q.get()
			self.sensor.setColour(msg.msg)
			print_info = (msg.sender_id, msg.receiver_id, msg.time_sent, msg.rssi)
			self.sensor.debug("Packet from %s\tto %s\tsent at time %.3f\thas RSSI = %f" % print_info)
		sleeptime = random.uniform(1, 2)
		api.Sleep(sleeptime)
